import EventEmitter from 'events' // 使用 events 包来实现发布/订阅
import runSaga from './runSaga'

/**
 * 返回一个 redux 中间件
 */
function createSagaMiddleware() {
  const channel = new EventEmitter() // 创建一个事件对象
  let boundRunSaga;
  /**
   * redux 中间件\
   * 内部会基于 runSaga 函数创建一个新函数
   */
  function sagaMiddleware({ getState, dispatch }) {
    // 基于 runSaga 函数创建一个新函数 新函数的 this 为 null 并且指定第一个参数
    boundRunSaga = runSaga.bind(null, { channel, dispatch, getState })
    return function (next) {
      return function (action) {
        next(action) // 执行下一个中间件
        channel.emit(action.type, action) // 发射一个 action.type 事件
      }
    }
  }

  /**
   * 接收一个 saga 并运行这个 saga
   * @param {*} saga 接收一个 saga
   */
  sagaMiddleware.run = function (saga) {
    boundRunSaga(saga)
  }

  return sagaMiddleware
}

export default createSagaMiddleware
